<?php

/**
 * @Description 
 *
 * @author linyi <linweiyxz@163.com>
 * @date 2018-6-24
 */

namespace Plugs\Controller;

use Think\Controller;
use Common\Service\FileService;

class UploadController extends Controller {

    public function upfile() {
        $uptype = I('get.uptype');
        if (!in_array($uptype, array('local', 'qiniu', 'oss'))) {
            $uptype = sysconf('storage_type');
        }
        $get = I('get.');
        $mode = isset($get['mode']) && $get['mode'] !== '' ? $get['mode'] : 'one';
        $types = isset($get['type']) && $get['type'] !== '' ? $get['type'] : 'jpg,png';
        $filed = isset($get['field']) && $get['field'] !== '' ? $get['field'] : 'file';
        $this->assign('mimes', FileService::getFileMine($types));
        $this->assign('field', $filed);
        $this->assign('mode', $mode);
        $this->assign('types', $types);
        $this->assign('uptype', $uptype);
        $this->display();
    }

    /**
     * 通用文件上传
     * @return \think\response\Json
     * @throws \think\Exception
     * @throws \think\exception\PDOException
     * @throws \OSS\Core\OssException
     */
    public function upload() {
        $names = I('post.md5', '', 'trim');
        $ext = pathinfo($_FILES['file']['name'], 4);
        $filename = date('Y') . "/{$names}.{$ext}";
        // 文件上传Token验证
        if (I('post.token') !== md5($filename . session_id())) {
            $this->ajaxReturn(['code' => 'ERROR', 'msg' => '文件上传验证失败']);
        }
        $upload = new \Think\Upload(); // 实例化上传类
        $upload->maxSize = sysconf('storage_local_siez') * 1024 * 1024; // 设置附件上传大小
        $upload->exts = explode(',', sysconf('storage_local_exts')); // 设置附件上传类型
        $upload->rootPath = './Public';
        $upload->savePath = '/upload/';
        $upload->subName = array('date', 'Y');
        $upload->saveName = $names;
        // 文件上传处理
        if ($upload->upload()) {
            if (($site_url = FileService::getFileUrl($filename, 'local'))) {
                $this->ajaxReturn(['data' => ['site_url' => $site_url], 'code' => 'SUCCESS', 'msg' => '文件上传成功']);
            }
        } else {
            $this->ajaxReturn(array('code' => 'ERROR', 'msg' => $upload->getError()));
        }
        $this->ajaxReturn(array('code' => 'ERROR', 'msg' => '文件上传失败'));
    }

    /**
     * 文件状态检查
     * @throws \OSS\Core\OssException
     * @throws \think\Exception
     * @throws \think\exception\PDOException
     */
    public function upstate() {
        $post = I('post.');
        $filename = date('Y', time()) . '/' . $post['md5'] . '.' . pathinfo($post['filename'], 4);
        // 检查文件是否已上传
        if (($site_url = FileService::getFileUrl($filename))) {
            $this->ajaxReturn(array('data' => array('site_url' => $site_url), 'code' => 'IS_FOUND', 'time' => time()));
        }
        // 需要上传文件，生成上传配置参数
        $config = ['uptype' => $post['uptype'], 'file_url' => $filename];
        switch (strtolower($post['uptype'])) {
            case 'local':
                $config['server'] = FileService::getUploadLocalUrl();
                $config['token'] = md5($filename . session_id());
                break;
            case 'qiniu':
                $config['server'] = FileService::getUploadQiniuUrl(true);
                $config['token'] = $this->_getQiniuToken($filename);
                break;
            case 'oss':
                $time = time() + 3600;
                $policyText = [
                    'expiration' => date('Y-m-d', $time) . 'T' . date('H:i:s', $time) . '.000Z',
                    'conditions' => [['content-length-range', 0, 1048576000]],
                ];
                $config['server'] = FileService::getUploadOssUrl();
                $config['policy'] = base64_encode(json_encode($policyText));
                $config['site_url'] = FileService::getBaseUriOss() . $filename;
                $config['signature'] = base64_encode(hash_hmac('sha1', $config['policy'], sysconf('storage_oss_secret'), true));
                $config['OSSAccessKeyId'] = sysconf('storage_oss_keyid');
        }
        $config['code'] = 'NOT_FOUND';
        $this->ajaxReturn(array('code' => 'NOT_FOUND', 'data' => $config, 'time' => time()));
    }

    /**
     * 生成七牛文件上传Token
     * @param string $key
     * @return string
     * @throws \think\Exception
     * @throws \think\exception\PDOException
     */
    protected function _getQiniuToken($key) {
        $baseUrl = FileService::getBaseUriQiniu();
        $bucket = sysconf('storage_qiniu_bucket');
        $accessKey = sysconf('storage_qiniu_access_key');
        $secretKey = sysconf('storage_qiniu_secret_key');
        $params = [
            "scope" => "{$bucket}:{$key}", "deadline" => 3600 + time(),
            "returnBody" => "{\"data\":{\"site_url\":\"{$baseUrl}$(key)\",\"file_url\":\"$(key)\"}, \"code\": \"SUCCESS\"}",
        ];
        $data = str_replace(['+', '/'], ['-', '_'], base64_encode(json_encode($params)));
        return $accessKey . ':' . str_replace(['+', '/'], ['-', '_'], base64_encode(hash_hmac('sha1', $data, $secretKey, true))) . ':' . $data;
    }

}
